#include "header.hpp"
using namespace std;

//Subject: design pattern
//Simple Factory Pattern
void test13(){
    //Abstract class
    class Operation{
    private:
        double a;
        double b;

    public:
        void setA(double a){ this->a = a; }
        double getA(){ return a; }

        void setB(double b){ this->b = b; }
        double getB(){ return b; }

        virtual double getResult() = 0;
    };

    class OperationAdd : public Operation{
    public:
        double getResult(){
            return getA() + getB();
        }
    };

    class OperationSub : public Operation{
    public:
        double getResult(){
            return getA() - getB();
        }
    };

    class OperationMul : public Operation{
    public:
        double getResult(){
            return getA() * getB();
        }
    };

    class OperationDiv : public Operation{
    public:
        double getResult(){
            if(getB() == 0){
                cerr << "The divisor cannot be 0" << endl;
                exit(1);
            }
            return getA() / getB();
        }
    };

    class OperationFactory{
    public:
        static Operation* createOperate(string operate){
            Operation* oper = nullptr;

            if(operate == "+"){
                oper = new OperationAdd();
            }

            if(operate == "-"){
                oper = new OperationSub();
            }

            if(operate == "*"){
                oper = new OperationMul();
            }

            if(operate == "/"){
                oper = new OperationDiv();
            }

            return oper;
        }
    };


    //User
    Operation* oper1;
    oper1 = OperationFactory::createOperate("+");
    oper1->setA(1);
    oper1->setB(2);
    cout << oper1->getResult() << endl;

    Operation* oper2;
    oper2 = OperationFactory::createOperate("/");
    oper2->setA(10);
    oper2->setB(3);
    cout << oper2->getResult() << endl;
}
